package com.by.cloud.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by.cloud.common.BaseContext;
import com.by.cloud.exception.BusinessException;
import com.by.cloud.exception.ErrorCode;
import com.by.cloud.exception.ThrowUtils;
import com.by.cloud.mapper.CategoryMapper;
import com.by.cloud.mapper.PictureMapper;
import com.by.cloud.model.dto.category.CategoryUpdateDto;
import com.by.cloud.model.entity.Category;
import com.by.cloud.model.entity.Picture;
import com.by.cloud.model.entity.PictureCategoryTag;
import com.by.cloud.service.CategoryService;
import com.by.cloud.service.PictureCategoryTagService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author lwr
 * @description 针对表【category】的数据库操作Service实现
 * @createDate 2024-12-17 10:06:01
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {
    @Resource
    private PictureCategoryTagService pictureCategoryTagService;
    /**
     * 注入mapper 防止循环依赖
     */
    @Resource
    private PictureMapper pictureMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addBatchCategories(List<String> categoryNameList) {
        if (CollUtil.isEmpty(categoryNameList)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "分类名称不能为空");
        }
        // 判断分类是否存在
        List<Category> categoryList = this.list();
        List<String> newCategoryNameList = new ArrayList<>();
        if (CollUtil.isNotEmpty(categoryList)) {
            // 提取数据库中的已有分类名称
            Set<String> existingNames = categoryList.stream()
                    .map(Category::getCategoryName)
                    .collect(Collectors.toSet());

            // 只保留那些不在数据库中的名称
            newCategoryNameList = categoryNameList.stream()
                    .filter(name -> !existingNames.contains(name))
                    .toList();
        }
        if (CollUtil.isEmpty(newCategoryNameList)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "分类名称重复");
        }
        //保留在数据库的集合
        List<Category> newCategoryList = new ArrayList<>();
        //获取当前登录用户是谁
        Long userId = BaseContext.getCurrentId();
        for (String name : newCategoryNameList) {
            Category category = new Category();
            category.setCategoryName(name);
            category.setUserId(userId);
            newCategoryList.add(category);
        }
        return this.saveBatch(newCategoryList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByCategoryId(List<Long> ids) {
        //当ids里面有的可以删除有的不能删除，是否保留可以删除的拥有标签图片的分类后面再仔细探讨
        //当前逻辑是 直接全部可删或者部分不可删就抛出异常

        ThrowUtils.throwIf(CollUtil.isEmpty(ids), ErrorCode.PARAMS_ERROR);

        // 首先查看当前分类下是否还有标签图片
        List<PictureCategoryTag> pictureCategoryTagList = pictureCategoryTagService.lambdaQuery()
                .in(PictureCategoryTag::getCategoryId, ids)
                .list();
        if (CollUtil.isNotEmpty(pictureCategoryTagList)) {
            //还有标签图片，不能删除
            Set<Long> categoryIds = pictureCategoryTagList.stream()
                    .map(PictureCategoryTag::getCategoryId)
                    .collect(Collectors.toSet());
            //获取分类集合以获取分类名称
            List<Category> categoryList = this.listByIds(categoryIds);
            List<String> nameList = categoryList.stream()
                    .map(Category::getCategoryName)
                    .toList();
            ThrowUtils.throwIf(CollUtil.isEmpty(nameList), ErrorCode.NOT_FOUND_ERROR);
            //不符合删除条件的以逗号分隔的分类名称
            String strNameList = String.join(",", nameList);
            throw new BusinessException(ErrorCode.PARAMS_ERROR, strNameList + " 等分类还有未删除的图片，请删除完分类下的图片再删除！");
        }

        //到这里说明集合可以删除
        return this.removeBatchByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCategoryNameById(CategoryUpdateDto categoryUpdateDto) {
        //参数合法性校验
        ThrowUtils.throwIf(categoryUpdateDto == null, ErrorCode.PARAMS_ERROR);
        Long categoryId = categoryUpdateDto.getCategoryId();
        String categoryName = categoryUpdateDto.getCategoryName();
        ThrowUtils.throwIf(categoryId == null || StrUtil.isBlank(categoryName), ErrorCode.PARAMS_ERROR);

        // 查看是否有对应的分类数据
        Category category = this.getById(categoryId);
        ThrowUtils.throwIf(category == null, ErrorCode.NOT_FOUND_ERROR);

        // 修改分类名称,先查看是否名称一致或者重复
        if (category.getCategoryName().equals(categoryName)) {
            // 名称一致则直接结束
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"修改的分类名称一致！");
        }
        boolean exists = this.lambdaQuery()
                .eq(Category::getCategoryName, categoryName)
                .exists();
        ThrowUtils.throwIf(exists, ErrorCode.PARAMS_ERROR, "想要更新的分类名称已经存在");

        //更新分类名称
        boolean result = this.lambdaUpdate()
                .eq(Category::getCategoryId, categoryId)
                .set(Category::getCategoryName, categoryName)
                .set(Category::getEditTime, LocalDateTime.now())
                .update();
        // 更新分类下照片的分类名称
        List<PictureCategoryTag> pictureCategoryTagList = pictureCategoryTagService.lambdaQuery()
                .select(PictureCategoryTag::getPictureId)
                .eq(PictureCategoryTag::getCategoryId, categoryId)
                .list();
        //如果没有，直接返回
        if (CollUtil.isEmpty(pictureCategoryTagList)) {
            return result;
        }

        // 如果有的话更新
        List<Long> pictureIds = pictureCategoryTagList.stream()
                .map(PictureCategoryTag::getPictureId)
                .toList();
        int updateNums = pictureMapper.update(new UpdateWrapper<Picture>()
                .set("category", categoryName)
                .set("edit_time", LocalDateTime.now())
                .in("pic_id", pictureIds));

        return result && updateNums > 0;
    }
}




